home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / APPLI / EUREKA_2.12 / 3D2POV18 / SOURCE / 3D22POV.C next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  15.4 KB  |  618 lines

  1. /*-------------------------------------------------------------------------
  2.  
  3.              3D2 to Raytracer File Converter
  4.                Copyright (c) 1992 by Steve Anger
  5.  
  6.    Converts files from Cyber Sculpt 3D2 format (Atari) to POV-Ray or Vivid
  7.  raytracer formats. This file may be freely modified and distributed.
  8.  
  9.                        CompuServe: 70714,3113
  10.                         YCCMR BBS: (708)358-5611
  11.  
  12. --------------------------------------------------------------------------*/
  13.  
  14. #define __GNUC__
  15.  
  16. #ifndef __GNUC__
  17. #include <alloc.h>
  18. #endif
  19.  
  20. #include <stdio.h>
  21. #include <portab.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <math.h>
  25.  
  26.  
  27. #include "rayopt.h"
  28.  
  29.  
  30.  
  31. #ifdef __TURBOC__
  32. extern unsigned _stklen = 16384;
  33. #endif
  34.  
  35. #define VERSION "v1.8"
  36.  
  37. #define ASPECT 1.333
  38.  
  39. #define POV10  0
  40. #define POV20  1
  41. #define VIVID  2
  42. #define RAW    99
  43.  
  44. typedef struct
  45. {
  46.     float  x, y, z;
  47. } Vector;
  48.  
  49.  
  50. typedef struct
  51. {
  52.     int  x, y, z;
  53. } IVector;
  54.  
  55.  
  56. typedef struct
  57. {
  58.     float red;
  59.     float green;
  60.     float blue;
  61. } Palette;
  62.  
  63.  
  64. typedef struct
  65. {
  66.     int    vert_a;       /* Vertex A of the triangle */
  67.     int    vert_b;       /*   "    B  "  "      "    */
  68.     int    vert_c;       /*   "    C  "  "      "    */
  69.     int    colour;       /* Colour of triangle */
  70. } Triangle;
  71.  
  72.  
  73. typedef unsigned char byte;
  74. typedef signed int word;
  75.  
  76.  
  77. /* Function prototype definitions */
  78. void process_args (int argc, char *argv[]);
  79. byte read_byte (FILE *f);
  80. word read_word (FILE *f);
  81. void read_3d2_header (void);
  82. void convert_object (void);
  83. void write_intro (void);
  84. void write_triangle (Vector a, Vector b, Vector c, Palette pal);
  85. void write_summary (void);
  86. void write_light (Vector pos, float red, float green, float blue);
  87. void write_camera (Vector pos, Vector target, float lens);
  88. char upcase (char c);
  89. void fswap (float *a, float *b);
  90.  
  91. /* Global variables */
  92. FILE      *in;            /* Input file */
  93. FILE      *out;           /* Output file */
  94. char      infile[64];     /* Input file name */
  95. char      outfile[64];    /* Output file name */
  96. Vector    look_at;        /* Location to look at */
  97. Vector    view_point;     /* Location of view_point */
  98. int       verbose;        /* Verbose messages flag */
  99. int       format;         /* Output format */
  100. float     smooth;         /* Smooth triangles who's normals differ by */
  101.               /* less than this angle (degrees) */
  102.  
  103. /* 3D2 Header infomation */
  104. int       obj_count;       /* Number of objects contained in file */
  105. int       light_on[3];     /* 1 = Light source is on, 0 = off */
  106. float     light_bright[3]; /* Light source brightness */
  107. Vector    light_pos[3];    /* Light source position */
  108. Palette   pal[16];         /* Colour palette for objects */
  109.  
  110. /* 3D2 Object information */
  111. char      obj_name[12];   /* Name of current object */
  112. int       vert_count;     /* Number of vertices in object */
  113. IVector   *vert;          /* Pointer to array of vertices */
  114. int       tri_count;      /* Number of triangular faces in object */
  115. int       degen_count;    /* Degenerate triangles */
  116.  
  117.  
  118.  
  119. int main (int argc, char* argv[])
  120. {
  121.     int i, total_vert, total_tri, total_degen, total_bounds;
  122.  
  123.     process_args (argc, argv);
  124.  
  125.     if (format != RAW) {
  126.     opt_set_format (format);
  127.     opt_set_quiet (!verbose);
  128.     opt_set_smooth (smooth);
  129.     opt_set_dec (2);
  130.     opt_set_fname (outfile, "");
  131.     }
  132.  
  133.     in = fopen (infile, "rb");
  134.     if (in == NULL)
  135.     abortmsg ("Error opening input file.", 1);
  136.  
  137.     out = fopen (outfile, "w");
  138.     if (out == NULL)
  139.     abortmsg ("Error opening output file.", 1);
  140.  
  141.     total_vert   = 0;
  142.     total_tri    = 0;
  143.     total_degen  = 0;
  144.     total_bounds = 0;
  145.  
  146.     read_3d2_header();
  147.     write_intro();
  148.  
  149.     printf ("  Object    Vertices    Triangles   Degen Tri   Bounds   Bnd Index\n");
  150.     printf ("---------- ----------- ----------- ----------- -------- -----------\n");
  151.  
  152.     for (i = 0; i < obj_count; i++) {
  153.     convert_object();
  154.  
  155.     printf ("     %6d      %6d      %6d   %6d    %8.2f\n",
  156.         vert_count, tri_count, degen_count,
  157.         opt_get_bounds(), opt_get_index());
  158.  
  159.     total_vert   += vert_count;
  160.     total_tri    += tri_count;
  161.     total_degen  += degen_count;
  162.     total_bounds += opt_get_bounds();
  163.     }
  164.  
  165.     write_summary();   /* Finish off the file */
  166.  
  167.     printf ("           =========== =========== =========== ========\n");
  168.     printf (" Totals       %6d      %6d      %6d   %6d\n",
  169.         total_vert, total_tri, total_degen, total_bounds);
  170.  
  171.     printf ("\nConverted %d object(s), ", obj_count);
  172.     printf ("%d light source(s).\n\n", light_on[0] + light_on[1] + light_on[2]);
  173.  
  174.     fclose(in);
  175.     fclose(out);
  176.  
  177.     return 0;
  178. }
  179.  
  180. void process_args (int argc, char *argv[])
  181. {
  182.     int i;
  183.  
  184.     printf ("\n");
  185.     printf ("3D2 to POV-Ray/Vivid Converter %s, ", VERSION);
  186.     printf ("Copyright (c) 1993 Steve Anger\n");
  187. #if defined(__GNUC__) && defined(i386)
  188.     printf ("32 bit version. DOS Extender Copyright (c) 1991 DJ Delorie\n");
  189. #endif
  190.     printf ("This program is freely distributable\n\n");
  191.  
  192.     if (argc < 2) {
  193.     printf ("Usage: 3d2-pov inputfile[.3d2] [outputfile] [options]\n\n");
  194.     printf ("Options: -lxnnn - Set look_at x coord to nnn\n");
  195.     printf ("         -lynnn -  '     '    y   '   '   ' \n");
  196.     printf ("         -lznnn -  '     '    z   '   '   ' \n");
  197.     printf ("         -vxnnn - Set view_point x coord to nnn\n");
  198.     printf ("         -vynnn -  '       '     y   '   '   ' \n");
  199.     printf ("         -vznnn -  '       '     z   '   '   ' \n");
  200.     printf ("         -snnn  - Smooth triangle boundaries with angles < nnn\n");
  201.     printf ("         -op    - Output to POV-Ray 1.0 format (default)\n");
  202.     printf ("         -op2   - Output to POV-Ray 2.0 format\n");
  203.     printf ("         -ov    - Output to Vivid 2.0 format\n");
  204.     printf ("         -or    - Output to RAW triangle format\n");
  205.     printf ("\n   e.g. 3d2-pov car.3d2 car.pov -s60.0\n\n");
  206.     exit(1);
  207.     }
  208.  
  209.     strcpy (infile, "");
  210.     strcpy (outfile, "");
  211.  
  212.     smooth  = 60.0;
  213.     verbose = 0;
  214.     format  = POV10;
  215.  
  216.     view_point.x = +50.0;
  217.     view_point.y = -50.0;
  218.     view_point.z = +50.0;
  219.  
  220.     look_at.x = 0.0;
  221.     look_at.y = 0.0;
  222.     look_at.z = 0.0;
  223.  
  224.     for (i = 1; i < argc; i++) {
  225.     if (argv[i][0] == '-' || argv[i][0] == '/') {
  226.         switch (upcase(argv[i][1])) {
  227.         case 'S': if (argv[i][2] == '\0')
  228.                   smooth = 60.0;
  229.               else
  230.                   sscanf (&argv[i][2], "%f", &smooth);
  231.               break;
  232.  
  233.         case 'L': switch (upcase(argv[i][2])) {
  234.                 case 'X': sscanf (&argv[i][3], "%f", &look_at.x);
  235.                       break;
  236.                 case 'Y': sscanf (&argv[i][3], "%f", &look_at.y);
  237.                       break;
  238.                 case 'Z': sscanf (&argv[i][3], "%f", &look_at.z);
  239.               }
  240.               break;
  241.  
  242.         case 'V': switch (upcase(argv[i][2])) {
  243.                 case 'X': sscanf (&argv[i][3], "%f", &view_point.x);
  244.                       break;
  245.                 case 'Y': sscanf (&argv[i][3], "%f", &view_point.y);
  246.                       break;
  247.                 case 'Z': sscanf (&argv[i][3], "%f", &view_point.z);
  248.               }
  249.               break;
  250.  
  251.             case 'O': switch (upcase(argv[i][2])) {
  252.                   case 'P': if (argv[i][3] == '2')
  253.                         format = POV20;
  254.                         else
  255.                         format = POV10;
  256.                         break;
  257.  
  258.                   case 'V': format = VIVID;
  259.                         break;
  260.  
  261.                   case 'R': format = RAW;
  262.                         break;
  263.                   }
  264.                   break;
  265.  
  266.         default:  printf ("Invalid option -%c, ignored.\n\n", argv[i][1]);
  267.         }
  268.     }
  269.     else if (strlen(infile) == 0) {
  270.         strcpy (infile, argv[i]);
  271.         add_ext (infile, "3d2", 0);
  272.     }
  273.     else if (strlen (outfile) == 0) {
  274.         strcpy (outfile, argv[i]);
  275.  
  276.         switch (format) {
  277.         case POV10:
  278.         case POV20: add_ext (outfile, "pov", 0); break;
  279.         case VIVID: add_ext (outfile, "v",   0); break;
  280.         case RAW:   add_ext (outfile, "raw", 0); break;
  281.         }
  282.     }
  283.     else
  284.         abortmsg ("Too many file names", 1);
  285.     }
  286.  
  287.     if (strlen (infile) == 0)
  288.     abortmsg ("No input file specified", 1);
  289.  
  290.     /* Prevent a division by zero error later on */
  291.     if ((view_point.x - look_at.x) == 0.0 && (view_point.z - look_at.z) == 0.0)
  292.     view_point.z -= 0.01;
  293.  
  294.     if (strlen (outfile) == 0) {
  295.     strcpy (outfile, infile);
  296.  
  297.     switch (format) {
  298.             case POV10:
  299.         case POV20: add_ext (outfile, "pov", 1); break;
  300.         case VIVID: add_ext (outfile, "v",   1); break;
  301.         case RAW:   add_ext (outfile, "raw", 1); break;
  302.     }
  303.     }
  304.  
  305.     if (format == POV10 || format == POV20)
  306.     fswap (&view_point.y, &view_point.z);
  307. }
  308.  
  309.  
  310. byte read_byte (FILE *f)
  311. {
  312.     return fgetc(f);
  313. }
  314.  
  315.  
  316. word read_word (FILE *f)
  317. {
  318.     byte bh, bl;
  319.     word res;
  320.  
  321.     bh = fgetc(f);
  322.     bl = fgetc(f);
  323.  
  324.     res = 256*bh + bl;
  325.  
  326.     /* A sign adjustment for non-16 bit machines. */
  327.     if (sizeof(word) > 2  &&  (res & 0x8000) != 0)
  328.     res = ((-1) << 16) | res;
  329.  
  330.     return (res);
  331. }
  332.  
  333.  
  334. void read_3d2_header()
  335. {
  336.     int i;
  337.     word temp;
  338.  
  339.     if (read_word(in) != 0x3D02)
  340.     abortmsg ("Input file is not 3D2 format.", 1);
  341.  
  342.     obj_count = read_word(in);
  343.  
  344.     light_on[0] = read_word(in);
  345.     light_on[1] = read_word(in);
  346.     light_on[2] = read_word(in);
  347.  
  348.     light_bright[0] = read_word(in)/7.0;
  349.     light_bright[1] = read_word(in)/7.0;
  350.     light_bright[2] = read_word(in)/7.0;
  351.  
  352.     read_word(in);       /* Skip the ambient light level */
  353.  
  354.     light_pos[0].z = (float)read_word(in);
  355.     light_pos[1].z = (float)read_word(in);
  356.     light_pos[2].z = (float)read_word(in);
  357.  
  358.     light_pos[0].y = (float)read_word(in);
  359.     light_pos[1].y = (float)read_word(in);
  360.     light_pos[2].y = (float)read_word(in);
  361.  
  362.     light_pos[0].x = (float)read_word(in);
  363.     light_pos[1].x = (float)read_word(in);
  364.     light_pos[2].x = (float)read_word(in);
  365.  
  366.     if (format == POV10 || format == POV20) {
  367.     fswap (&light_pos[0].y, &light_pos[0].z);
  368.     fswap (&light_pos[1].y, &light_pos[1].z);
  369.     fswap (&light_pos[2].y, &light_pos[2].z);
  370.     }
  371.  
  372.     for (i = 0; i < 16; i++) {
  373.     temp = read_word(in);
  374.     pal[i].red   = ((temp & 0x0700) >> 8)/7.0;
  375.     pal[i].green = ((temp & 0x0070) >> 4)/7.0;
  376.     pal[i].blue  = (temp & 0x0007)/7.0;
  377.     }
  378.  
  379.     for (i = 0; i < 188; i++)
  380.     read_byte(in);
  381. }
  382.  
  383.  
  384. void convert_object()
  385. {
  386.     int    i, va, vb, vc, col;
  387.     Vector a, b, c;
  388.  
  389.     for (i = 0; i < 9; i++)
  390.     obj_name[i] = read_byte(in);
  391.  
  392.     cleanup_name (obj_name);
  393.  
  394.     printf (" %-8s", obj_name);
  395.     fflush (stdout);
  396.  
  397.     if (format == RAW)
  398.     fprintf (out, "%s\n", obj_name);
  399.  
  400.     vert_count = read_word(in);
  401.  
  402.     if (vert_count > 0) {
  403.     vert = malloc (vert_count * sizeof(*vert));
  404.     if (vert == NULL)
  405.         abortmsg ("Insufficient memory for vertices.", 1);
  406.     }
  407.  
  408.     for (i = 0; i < vert_count; i++) {
  409.     vert[i].x = read_word(in);
  410.     vert[i].y = read_word(in);
  411.     vert[i].z = read_word(in);
  412.     }
  413.  
  414.     /* Tell optimizer how many vertices to expect */
  415.     if (format != RAW)
  416.     opt_set_vert (vert_count);
  417.  
  418.     tri_count = read_word(in);
  419.     degen_count = 0;
  420.  
  421.     for (i = 0; i < tri_count; i++) {
  422.     va = read_word(in);
  423.     vb = read_word(in);
  424.     vc = read_word(in);
  425.     read_byte(in);
  426.     col = read_byte(in);
  427.  
  428.     a.x = vert[va].x / 100.0;
  429.     a.y = vert[va].y / 100.0;
  430.     a.z = vert[va].z / 100.0;
  431.  
  432.     b.x = vert[vb].x / 100.0;
  433.     b.y = vert[vb].y / 100.0;
  434.     b.z = vert[vb].z / 100.0;
  435.  
  436.     c.x = vert[vc].x / 100.0;
  437.     c.y = vert[vc].y / 100.0;
  438.     c.z = vert[vc].z / 100.0;
  439.  
  440.     if (format == POV10 || format == POV20) {
  441.         fswap (&a.y, &a.z);
  442.         fswap (&b.y, &b.z);
  443.         fswap (&c.y, &c.z);
  444.     }
  445.  
  446.     write_triangle (a, b, c, pal[col]);
  447.     }
  448.  
  449.     if (vert_count > 0)
  450.     free (vert);
  451.  
  452.     if (format != RAW) {
  453.     fclose(out);
  454.     opt_write_file (obj_name);
  455.     out = fopen (outfile, "a");
  456.     }
  457. }
  458.  
  459.  
  460.  
  461. void write_intro()
  462. {
  463.     switch (format) {
  464.     case POV10:
  465.         case POV20:
  466.         fprintf (out, "/* Converted from file %s with 3D2-POV %s */\n\n",
  467.              infile, VERSION);
  468.         fprintf (out, "#include \"colors.inc\"\n");
  469.         fprintf (out, "#include \"textures.inc\"\n\n");
  470.         break;
  471.  
  472.     case VIVID:
  473.         fprintf (out, "/* Converted from file %s with 3D2-POV %s */\n\n",
  474.              infile, VERSION);
  475.         fprintf (out, "#include color.vc\n\n");
  476.         break;
  477.     }
  478. }
  479.  
  480.  
  481. void write_triangle (Vector a, Vector b, Vector c, Palette pal)
  482. {
  483.     switch (format) {
  484.         case POV10:
  485.     case POV20:
  486.     case VIVID:
  487.         opt_set_color (pal.red, pal.green, pal.blue);
  488.  
  489.         if (opt_add_tri (a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z) < 0)
  490.         ++degen_count;
  491.  
  492.         break;
  493.  
  494.     case RAW:
  495.         fprintf (out, "%.2f %.2f %.2f  %.2f %.2f %.2f  %.2f %.2f %.2f\n",
  496.              a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z);
  497.         break;
  498.     }
  499. }
  500.  
  501.  
  502. void write_summary()
  503. {
  504.     int   i;
  505.  
  506.     switch (format) {
  507.         case POV10:
  508.     case POV20:
  509.     case VIVID:
  510.         fclose(out);
  511.         opt_finish();
  512.         out = fopen (outfile, "a");
  513.  
  514.         for (i = 0; i < 3; i++) {
  515.         if (light_on[i])
  516.             write_light (light_pos[i], light_bright[i], light_bright[i], light_bright[i]);
  517.         }
  518.  
  519.         write_camera (view_point, look_at, 35.0);
  520.         break;
  521.     }
  522. }
  523.  
  524.  
  525. void write_light (Vector pos, float red, float green, float blue)
  526. {
  527.     switch (format) {
  528.     case POV10:
  529.         fprintf (out, "object {\n");
  530.         fprintf (out, "    light_source { <%.4f %.4f %.4f> color red %4.2f green %4.2f blue %4.2f }\n",
  531.               pos.x, pos.y, pos.z, red, green, blue);
  532.         fprintf (out, "}\n\n");
  533.         break;
  534.  
  535.     case POV20:
  536.         fprintf (out, "light_source {\n");
  537.         fprintf (out, "    <%.4f, %.4f, %.4f> color red %4.2f green %4.2f blue %4.2f\n",
  538.                    pos.x, pos.y, pos.z, red, green, blue);
  539.         fprintf (out, "}\n\n");
  540.         break;
  541.  
  542.     case VIVID:
  543.         fprintf (out, "light {\n");
  544.         fprintf (out, "    type point\n");
  545.         fprintf (out, "    position %.4f %.4f %.4f\n",
  546.               pos.x, pos.y, pos.z);
  547.         fprintf (out, "    color %4.2f %4.2f %4.2f\n",
  548.                  red, green, blue);
  549.         fprintf (out, "}\n\n");
  550.         break;
  551.     }
  552. }
  553.  
  554.  
  555. void write_camera (Vector pos, Vector target, float lens)
  556. {
  557.     switch (format) {
  558.     case POV10:
  559.         fprintf (out, "camera {\n");
  560.         fprintf (out, "   location <%.4f %.4f %.4f>\n",
  561.                   pos.x, pos.y, pos.z);
  562.         fprintf (out, "   direction <0 0 %.2f>\n", lens/35.0);
  563.         fprintf (out, "   up <0 1 0>\n");
  564.         fprintf (out, "   sky  <0 1 0>\n");
  565.         fprintf (out, "   right <%.3f 0 0>\n", ASPECT);
  566.         fprintf (out, "   look_at <%.4f %.4f %.4f>\n",
  567.                   target.x, target.y, target.z);
  568.         fprintf (out, "}\n\n");
  569.         break;
  570.  
  571.     case POV20:
  572.         fprintf (out, "camera {\n");
  573.         fprintf (out, "   location <%.4f, %.4f, %.4f>\n",
  574.                   pos.x, pos.y, pos.z);
  575.         fprintf (out, "   direction <0, 0, %.2f>\n", lens/35.0);
  576.         fprintf (out, "   up <0, 1, 0>\n");
  577.         fprintf (out, "   sky  <0, 1, 0>\n");
  578.         fprintf (out, "   right <%.3f, 0, 0>\n", ASPECT);
  579.         fprintf (out, "   look_at <%.4f, %.4f, %.4f>\n",
  580.                   target.x, target.y, target.z);
  581.         fprintf (out, "}\n\n");
  582.         break;
  583.  
  584.     case VIVID:
  585.         fprintf (out, "studio {\n");
  586.         fprintf (out, "    from %.4f %.4f %.4f\n", pos.x, pos.y, pos.z);
  587.         fprintf (out, "    at %.4f %.4f %.4f\n",
  588.                    target.x, target.y, target.z);
  589.         fprintf (out, "    up 0 0 1\n");
  590.         fprintf (out, "    angle %.2f\n",
  591.                    2.0 * (180.0/M_PI) * atan (35.0/lens) / ASPECT);
  592.         fprintf (out, "    aspect %.3f\n", ASPECT);
  593.         fprintf (out, "    resolution 320 200\n");
  594.         fprintf (out, "    antialias none\n");
  595.         fprintf (out, "}\n\n");
  596.         break;
  597.     }
  598. }
  599.  
  600.  
  601. char upcase (char c)
  602. {
  603.     if (c >= 'a' && c <= 'z')
  604.     c = c - 'a' + 'A';
  605.  
  606.     return c;
  607. }
  608.  
  609.  
  610. void fswap (float *a, float *b)
  611. {
  612.     float temp;
  613.  
  614.     temp = *a;
  615.     *a = *b;
  616.     *b = temp;
  617. }
  618.